home *** CD-ROM | disk | FTP | other *** search
/ Business Shareware / Business Shareware.iso / start / disk / combi110 / combi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-30  |  10.8 KB  |  341 lines

  1. /*
  2.  *  This program is copyright (C) 1992 by Vadim V. Vlasov, Moscow, Russia.
  3.  *
  4.  * The source is supplied as an example of interface to COMBI-disk (C)
  5.  * device driver. You may change the source as You wish, however I'm not
  6.  * responsible for the results of Your changes.
  7.  *
  8.  * The program is written for MS C 6.0 and may be compiled in TINY or
  9.  * SMALL memory model.
  10.  *
  11.  * If You don't have ANSI.SYS installed or want to redirect output to a file
  12.  * You may define NO_ANSI and recompile the program.
  13.  *
  14.  */
  15.  
  16.  
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <dos.h>
  20. #include "ioctl.h"    /* definitions of structures and control codes */
  21.  
  22. #ifndef  NO_ANSI
  23. #define  bold(string)        "\x1b[1m"#string"\x1b[0m"
  24. #define  red_bold(string)    "\x1b[1;31m"#string"\x1b[0m"
  25. #define  yellow_bold(string) "\x1b[1;33m"#string"\x1b[0m"
  26. #define  cyan_bold(string)   "\x1b[1;36m"#string"\x1b[0m"
  27. #else
  28. #define  bold(string)        #string
  29. #define  red_bold(string)    #string
  30. #define  yellow_bold(string) #string
  31. #define  cyan_bold(string)   #string
  32. #endif
  33.  
  34. main(int argc, char *argv[])
  35. {
  36.   struct combi_status cmb_st;
  37.   char   choice, drive=2;
  38.   union  REGS  r;
  39.   void far * ptr;
  40.   int i,j;
  41.   char   *chpt, optchar;
  42.   char   oldopt, opt;
  43.  
  44. /*
  45.  * Scan all drives and try to read IOCtl packet of length sizeof(cmb_st).
  46.  * If successful then probably that drive is COMBI's RAM disk. To ensure
  47.  * this we check that first 6 bytes of returned packet are "COMBI\0".
  48.  */
  49.  
  50.   do {
  51.     drive++;
  52.     r.x.ax=0x4404;
  53.     r.h.bl=drive;
  54.     r.x.cx=sizeof(cmb_st);
  55.     r.x.dx=(unsigned)&cmb_st;
  56.   } while (((intdos(&r,&r)!=sizeof(cmb_st))||
  57.            (r.x.cflag & 0x1)||
  58.            strcmp(cmb_st.ID_name,"COMBI"))&&(drive < 16));
  59.  
  60.   if(drive >= 16) {
  61.     printf(red_bold(Error: COMBI-disk not installed!(?)) "\n");
  62.     exit(1);
  63.   }
  64.  
  65.   printf("\t" yellow_bold(COMBI-disk version %1d.%02d installed as drive %c:) "\n",
  66.           cmb_st.version >> 8, cmb_st.version & 0xff, drive+'A'-1);
  67.  
  68.   if(argc > 1) {
  69.     optchar = '\0';
  70.     oldopt = opt = cmb_st.COMBI_options;
  71.  
  72.     for(i=1; i < argc; i++) {   /* Scan all command line arguments. */
  73.  
  74.       strlwr(argv[i]);
  75.       if(isdigit(*argv[i]) || *argv[i]=='-' || *argv[i]=='+') {
  76.  
  77.         /* If an argument is a number then try to reallocate COMBI's
  78.          * memory size.*/
  79.  
  80.         j = atoi(argv[i]);
  81.         if(change_mem(drive, cmb_st.version, j))
  82.           printf(red_bold(Can\'t reallocate memory!) "\a\n");
  83.         else
  84.           printf("Memory reallocated by %dK. ", j);
  85.       } else {
  86.         optchar = *argv[i];
  87.         chpt = argv[i]+1;
  88.         while(optchar) {
  89.           switch(optchar) {
  90.             case 'n':
  91.             /* Option 'n' - ignore (or not ignore if 'n-')
  92.              * 'sector not found error'. */
  93.               if(*chpt == '-') {
  94.                 opt &= ~OPT_NO_SNF;   /* Reset the option bit */
  95.                 chpt++;
  96.               } else {
  97.                 opt |= OPT_NO_SNF;    /* Set the option bit   */
  98.                 if(*chpt == '+')
  99.                     chpt++;
  100.               }
  101.               optchar = *chpt++;
  102.               break;
  103.             case 'o':
  104.             /* Option 'o' - turn cache on.  */
  105.               if(*chpt == '-') {
  106.                 opt |= OPT_OFF;
  107.                 chpt++;
  108.               } else {
  109.                 opt &= ~OPT_OFF;
  110.                 if(*chpt == '+')
  111.                     chpt++;
  112.               }
  113.               optchar = *chpt++;
  114.               break;
  115.             case 'b':
  116.             /* Option 'b' - turn background writing
  117.              * (== write caching) on.  */
  118.               if(*chpt == '-') {
  119.                 opt &= ~OPT_WR_ON;
  120.                 chpt++;
  121.               } else {
  122.                 opt |= OPT_WR_ON;
  123.                 if(*chpt == '+')
  124.                     chpt++;
  125.               }
  126.               optchar = *chpt++;
  127.               break;
  128.             case 'i':
  129.             /* Option 'i' - write immediately
  130.              * (or enable delayed writing if 'i-') in effect only if
  131.              * write caching (background writing) is on.  */
  132.               if(*chpt == '-') {
  133.                 opt &= ~OPT_DW_OFF;
  134.                 chpt++;
  135.               } else {
  136.                 opt |= OPT_DW_OFF;
  137.                 if(*chpt == '+')
  138.                     chpt++;
  139.               }
  140.               optchar = *chpt++;
  141.               break;
  142.             case 'z':
  143.             /* Option 'z' - freeze cache - no new sectors are read into
  144.              * cache after freezing and only that are in cache may be written
  145.              * in background.   */
  146.               if(*chpt == '-') {
  147.                 opt &= ~OPT_FREEZE;
  148.                 chpt++;
  149.               } else {
  150.                 opt |= OPT_FREEZE;
  151.                 if(*chpt == '+')
  152.                     chpt++;
  153.               }
  154.               optchar = *chpt++;
  155.               break;
  156.             case 'f':
  157.             /* Option 'z' - fix memory setting - disables automatic reallocation
  158.              * of XMS memory when it is requested by other programs.  */
  159.               if(*chpt == '-') {
  160.                 opt &= ~OPT_MEM;
  161.                 chpt++;
  162.               } else {
  163.                 opt |= OPT_MEM;
  164.                 if(*chpt == '+')
  165.                     chpt++;
  166.               }
  167.               optchar = *chpt;
  168.               break;
  169.             case 'r':
  170.             /* reset all counters */
  171.               if(reset_counters(drive, cmb_st.version))
  172.                   printf(red_bold(Can\'t reset counters!) "\a\n");
  173.               else
  174.                   printf("Counters reset. ");
  175.               optchar = *chpt++;
  176.               break;
  177.             default:
  178.               printf(red_bold(Invalid option: ) bold('%c') "\n", optchar);
  179.             case '?':
  180.               usage();
  181.           }
  182.         }
  183.       }
  184.     }
  185.     if(oldopt != opt) {
  186.       if(change_opt(drive, cmb_st.version, opt))
  187.         printf(red_bold(Can\'t change options!) "\a\n");
  188.       else
  189.         printf("Options changed.");
  190.     } else
  191.         printf("Options unchanged.");
  192.     printf("\n");
  193.   }
  194.  
  195.   r.x.ax=0x4404;                /* read again IOCtl packet */
  196.   r.h.bl=drive;
  197.   r.x.cx=sizeof(cmb_st);
  198.   r.x.dx=(unsigned)&cmb_st;
  199.   intdos(&r,&r);
  200.  
  201.   show_status(&cmb_st);   /* Show status returned by COMBI. */
  202.  
  203. }
  204.  
  205. show_status(struct combi_status *cmb_st)
  206. {
  207.   char  opt;
  208.  
  209.   printf("\n\t" bold(Current status:) "\n");
  210.  
  211.   printf("buffer size:  " cyan_bold(%5dK) "\n", cmb_st -> buff_size);
  212.  
  213.   printf("current size: " cyan_bold(%5dK) "\n", cmb_st -> curr_size);
  214.  
  215.   printf("total number of blocks:   " cyan_bold(%4d) " (" cyan_bold(%d) " sectors each)\n",
  216.           cmb_st -> n_blocks, cmb_st -> bl_sect);
  217.  
  218.   printf("current number of blocks: " cyan_bold(%4d) " (" cyan_bold(%d) " - RAM disk, " cyan_bold(%d) " - cache)\n",
  219.           cmb_st -> n_curr, cmb_st -> n_bl_RD, cmb_st -> n_bl_Cache);
  220.  
  221.   opt = cmb_st -> COMBI_options;
  222.   if(opt & OPT_WR_ON) {                /* only if write caching is on */
  223.     printf("dirty blocks: " cyan_bold(%d) ", errors: " cyan_bold(%d) "\n",
  224.             cmb_st ->  n_dirty, cmb_st -> n_errors);
  225.   };
  226.  
  227.   printf("\n\t" bold(Options in order:) "\n");
  228.  
  229.   if(!(opt & OPT_OFF)) {
  230.     printf("cache is " cyan_bold(on) " (%s),\n",
  231.            (opt & OPT_FREEZE) ? "frozen" : "not frozen");
  232.   printf("write caching is " cyan_bold(%s) ",\n",
  233.            (opt & OPT_WR_ON)  ? "on"     : "off");
  234.     if(opt & OPT_WR_ON) {
  235.     printf("delayed write is " cyan_bold(%s) ",\n",
  236.              (opt & OPT_DW_OFF) ? "off"    : "on");
  237.     };
  238.   } else {
  239.   printf("cache is " cyan_bold(off) ",\n");
  240.   };
  241.   printf("memory allocation is " cyan_bold(%s) ".\n",
  242.          (opt & OPT_MEM)    ? "fixed"  : "not fixed");
  243.  
  244.   printf("\n\t" bold(Statistics:) "\n");
  245.  
  246.   printf("RAM disk reads: " cyan_bold(% 6u/%-6u) "\n",
  247.           cmb_st -> read_RD_num, cmb_st -> read_RD_sect);
  248.  
  249.   printf("RAM disk writes:" cyan_bold(% 6u/%-6u) "\n",
  250.           cmb_st -> write_RD_num, cmb_st -> write_RD_sect);
  251.  
  252.   if(!(opt & OPT_OFF)){
  253.     printf("Hard disk reads - requested: " cyan_bold(% 6u/%-6u) ", passed to BIOS:" cyan_bold(% 6u/%-6u) "\n",
  254.             cmb_st -> read_rq,    cmb_st -> read_sect,
  255.             cmb_st -> read_rq_a,  cmb_st -> read_sect_a);
  256.     printf("Hard disk writes - requested:" cyan_bold(% 6u/%-6u) ", passed to BIOS:" cyan_bold(% 6u/%-6u) "\n",
  257.             cmb_st -> write_rq,   cmb_st -> write_sect,
  258.             cmb_st -> write_rq_a, cmb_st -> write_sect_a);
  259.   }
  260. }
  261.  
  262. change_mem(int drive, int ver, int memch)
  263. {
  264.   unsigned char ctl[12];
  265.   union REGS r;
  266.   *(int *)&ctl = ver;
  267.   if(memch > 0) {
  268.     ctl[2] = CMD_EXPAND;    /* command code for COMBI-disk - expand memory */
  269.     *(int *)&ctl[3] = memch;/* the amount of Kbytes to change memory size  */
  270.   } else {
  271.     ctl[2] = CMD_SHRINK;    /* command code for COMBI-disk - shrink memory */
  272.     *(int *)&ctl[3] = - memch;
  273.   }
  274.  
  275.   r.x.ax=0x4405;    /* DOS function: 'write IOCtl to block device' */
  276.   r.h.bl=drive;     /* device number  */
  277.   r.x.dx=(unsigned)&ctl;  /* address of IOCtl packet */
  278.   r.x.cx=5;         /* IOCtl packet length  */
  279.   intdos(&r,&r);
  280.   if(r.x.cflag & 01)      /* test for error return code */
  281.       return -1;
  282.   else
  283.       return 0;
  284. }
  285.  
  286. change_opt(int drive, int ver, int opt)
  287. {
  288.   unsigned char ctl[12];
  289.   union REGS r;
  290.   *(int *)&ctl = ver;
  291.   ctl[2] = CMD_CH_OPT;    /* command to COMBI-disk - change options */
  292.   ctl[3] = opt;           /* the byte with new options follows the command */
  293.  
  294.   r.x.ax=0x4405;
  295.   r.h.bl=drive;
  296.   r.x.dx=(unsigned)&ctl;
  297.   r.x.cx=4;
  298.   intdos(&r,&r);
  299.   if(r.x.cflag & 01)
  300.       return -1;
  301.   else
  302.       return 0;
  303. }
  304.  
  305. reset_counters(int drive, int ver)
  306. {
  307.   unsigned char ctl[12];
  308.   union REGS r;
  309.   *(int *)&ctl = ver;
  310.   ctl[2] = CMD_RESET_C;   /* command to COMBI-disk - reset counters */
  311.   ctl[3] = 7;             /* reset all three types of counters */
  312.  
  313.   r.x.ax=0x4405;
  314.   r.h.bl=drive;
  315.   r.x.dx=(unsigned)&ctl;
  316.   r.x.cx=4;
  317.   intdos(&r,&r);
  318.   if(r.x.cflag & 01)
  319.       return -1;
  320.   else
  321.       return 0;
  322. }
  323.  
  324. usage()
  325. {
  326.   printf("\t" yellow_bold(COMBI-disk (C) control program.) "\n"
  327.          "Copyright (C) 1992 by Vadim V. Vlasov, Moscow, Russia.\n");
  328.  
  329.   printf("Usage: " bold(COMBI [[+|-]#] [<option>[+|-]]...) "\n"
  330.          "where:\n"
  331.          "    " bold(# (number)) " - expand or shrink memory used by COMBI-disk,\n"
  332.          "    " bold(n) " - don't return 'sector not found' error,\n"
  333.          "    " bold(o) " - turn cache on ('" bold(o-) "' - turn off),\n"
  334.          "    " bold(b) " - turn write caching on ('" bold(b-) "' - off),\n"
  335.          "    " bold(i) " - start writing immediately ('" bold(i-) "' - delayed writing),\n"
  336.          "    " bold(f) " - fix memory settings ('" bold(f-) "' - release),\n"
  337.          "    " bold(z) " - freeze cache ('" bold(z-) "' - un-freese),\n"
  338.          "    " bold(r) " - reset all counters.\n");
  339.   exit(1);
  340. }
  341.